package com.shf.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.shf.config.ContentCensor;
import com.shf.constants.SystemCanstants;
import com.shf.domain.ResponseResult;
import com.shf.domain.dto.AddArticleDto;
import com.shf.domain.dto.ArticleDto;
import com.shf.domain.entity.*;
import com.shf.domain.vo.*;
import com.shf.enums.TextCensorResultEnum;
import com.shf.mapper.ArticleMapper;
import com.shf.mapper.RoleMapper;
import com.shf.service.*;
import com.shf.util.BeanCopyUtils;
import com.shf.util.RedisCache;
import com.shf.util.SecurityUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Collectors;

import static com.shf.constants.SystemCanstants.*;

/**
 * @author 叶枫
 * @date 2023/10/25.
 * ServiceImpl是mybatisPlus官方提供的
 */

@Service
public class ArticleServiceImpl extends ServiceImpl<ArticleMapper, Article> implements ArticleService {
    @Autowired
    private CategoryService categoryService;

    @Autowired
    private RedisCache redisCache;
    @Resource
    private UserService  userService;
    @Override
    public ResponseResult hotArticleList() {
        LambdaQueryWrapper<Article> queryWrapper = new LambdaQueryWrapper<>();
        //筛选出 文章的status 等于 0 的文章
        queryWrapper.eq(Article::getStatus,ARTICLE_STATUS_NORMAL);
        //根据浏览量进行降序排序
        queryWrapper.orderByDesc(Article::getViewCount);
        //展示十条文章
        Page<Article> page = new Page<>(ARTICLE_STATUS_CURRENT, ARTICLE_STATUS_SIZE);
        page(page,queryWrapper);
        //获取最终结果
        List<Article> articleList = page.getRecords();

//        //创建一个 对应的vo集合
//        List<HotArticleVO> hotArticleVOS  = new ArrayList<>();
//        //遍历 实体类集合
//        for (Article article : articleList) {
//            HotArticleVO vo = new HotArticleVO();
//            BeanUtils.copyProperties(article,vo);
//            //添加到vo类
//            hotArticleVOS.add(vo);
//        }
        //copyBean 让 vo实体类显示给前端
        List<HotArticleVO> hotArticleVOS = BeanCopyUtils.copyBeanList(articleList, HotArticleVO.class);
        //响应
        return ResponseResult.okResult(hotArticleVOS);
    }


    @Override
    public ResponseResult articleList(Integer pageNum, Integer pageSize, Long categoryId) {
        LambdaQueryWrapper<Article> queryWrapper = new LambdaQueryWrapper<>();
        //添加 条件 判断
        // 判断 categoryId是否为空 且 大于 0 如果满足 article中的categoryId 和 传入的 categoryId 比较
        queryWrapper.eq(Objects.nonNull(categoryId)&& categoryId > 0,Article::getCategoryId,categoryId);
        //只查询状态 为发布的文章
        queryWrapper.eq(Article::getStatus, 0);
        //置顶
        queryWrapper.orderByDesc(Article::getIsTop);
        //分页
        Page<Article> page = new Page<>(pageNum,pageSize);

        page(page,queryWrapper);
        //获取最终结果
        List<Article> articleList = page.getRecords();

        Set<Long> userIds = articleList.stream().map(Article::getUserId)
                .collect(Collectors.toSet());

        LambdaQueryWrapper<User> queryWrapper1 = new LambdaQueryWrapper<User>().in(User::getId, userIds);
        List<User> users = userService.list(queryWrapper1);
        Map<Long, String> longStringMap = users.stream().collect(Collectors.toMap(User::getId, User::getNickName));

        /**
         * 解决 没有categoryName system的形式
         */
        articleList.stream()
                .map(article -> {
                    //'article.getCategoryId()'表示从article表获取category_id字段，然后作为查询category表的name字段
                    Category category = categoryService.getById(article.getCategoryId());
                        //将每个 category对象的 name 赋值给 article.setCategoryName
                    article.setCategoryName(category.getName());
                    return article;
                }).collect(Collectors.toList());
        //copyBean
//        List<ArticleListVo> articleListVos = BeanCopyUtils.copyBeanList(articleList, ArticleListVo.class);

        List<ArticleListVo> articleListVos = articleList.stream().map(new Function<Article, ArticleListVo>() {
            @Override
            public ArticleListVo apply(Article article) {
                ArticleListVo articleListVo = new ArticleListVo();
                if (longStringMap.get(article.getUserId()) != null) {
                    articleListVo = BeanCopyUtils.copyBean(article, ArticleListVo.class);
                    articleListVo.setUserName(longStringMap.get(article.getUserId()));
                }
                return articleListVo;
            }
        }).collect(Collectors.toList());
        //把上面那行的查询结果和文章总数封装在PageVo(我们写的实体类)
        PageVo pageVo = new PageVo(articleListVos,page.getTotal());
        //返回结果
        return ResponseResult.okResult(pageVo);

    }
/**************************************************展示文章详情****************/
    @Resource
    private CollectService collectService;

    @Override
    public ResponseResult getArticleDetail(Long id, HttpServletRequest request) {
        //根据id查询文章
        Article article = getById(id);
        String token = request.getHeader("token");

        //从 redis 中获取浏览量
        Integer viewCount = redisCache.getCacheMapValue("viewCount", id.toString());
        //将他存入到查询结果后的   文章中
        article.setViewCount(viewCount.longValue());

        //转换成 vo
        ArticleDetailVo articleDetailVo = BeanCopyUtils.copyBean(article, ArticleDetailVo.class);
        //根据分类id查询分类名
        Category category = categoryService.getById(articleDetailVo.getCategoryId());
        //如果根据分类id查询的到分类名，那么就把查询到的值设置给ArticleDetailVo实体类的categoryName字段
        if(category!=null){
            articleDetailVo.setCategoryName(category.getName());
        }

        User userArticle = userService.getById(article.getUserId());
        articleDetailVo.setUserName(userArticle.getNickName());
        //根据文章id查询文章是否被当前用户收藏
            if(token!=null){
            LambdaQueryWrapper<Collect> queryWrapper = new LambdaQueryWrapper<>();
            LoginUser loginUser = SecurityUtils.getLoginUser();
            System.out.println(loginUser);
            queryWrapper.eq(Collect::getUserId,loginUser.getUser().getId())
                    .eq(Collect::getArticleId,id);
            int count = collectService.count(queryWrapper);
                System.out.println("count12"+ count);
            if(count>0){
                articleDetailVo.setCollectStatus(1);
            }else {
                articleDetailVo.setCollectStatus(0);
            }
            }
        //响应结果
        return ResponseResult.okResult(articleDetailVo);

    }

    @Override
    public ResponseResult updateViewCount(Long id) {
        Integer integer = new Integer(1);
        redisCache.incrementCacheMapValue("viewCount",id.toString(),integer.longValue());
        return ResponseResult.okResult();
    }


    /*************************新增文章*************************/
    @Autowired
    private ArticleTagService articleTagService;

    @Autowired
    private ArticleVoService articleVoService;

    @Override
    @Transactional/**添加事务保证一致性*/
    public ResponseResult add(AddArticleDto articleDto) {
        //添加 博客
        ArticleVo articlevo = BeanCopyUtils.copyBean(articleDto, ArticleVo.class);
        articlevo.setUserId(SecurityUtils.getUserId());

        boolean bl = this.handleTextScan(articlevo.getContent());
        if (!bl){
            return ResponseResult.okResult(201,"审核不通过");
        }
        articleVoService.save(articlevo);


        List<ArticleTag> articleTags = articleDto.getTags().stream()
                .map(tagId -> new ArticleTag(articlevo.getId(), tagId))
                .collect(Collectors.toList());

        //添加 博客和标签的关联
        articleTagService.saveBatch(articleTags);
        return ResponseResult.okResult(200,"发布成功");
    }

    @Resource
    private RoleMapper roleMapper;
    @Override
    public PageVo selectArticlePage(Article article, Integer pageNum, Integer pageSize) {
        LambdaQueryWrapper<Article> queryWrapper = new LambdaQueryWrapper();

        queryWrapper.like(StringUtils.hasText(article.getTitle()),Article::getTitle, article.getTitle());
        queryWrapper.like(StringUtils.hasText(article.getSummary()),Article::getSummary, article.getSummary());

        //查看当前登录用户的角色
        Long userId = SecurityUtils.getUserId();
        List<Long> longs = roleMapper.selectRoleIdByUserId(userId);
        if (!longs.contains(1L)){
            //否则查询当前用户的文章
            queryWrapper.eq(Article::getUserId,userId);
        }

        Page<Article> page = new Page<>();
        page.setCurrent(pageNum);
        page.setSize(pageSize);
        page(page,queryWrapper);

        //转换成VO
        List<Article> articles = page.getRecords();

        PageVo pageVo = new PageVo();
        pageVo.setTotal(page.getTotal());
        pageVo.setRows(articles);
        return pageVo;
    }
    //----------------------------修改文章-①根据文章id查询对应的文章--------------------------------

    @Override
    //①先查询根据文章id查询对应的文章
    public ArticleByIdVo getInfo(Long id) {
        Article article = getById(id);
        //获取关联标签
        LambdaQueryWrapper<ArticleTag> articleTagLambdaQueryWrapper = new LambdaQueryWrapper<>();
        articleTagLambdaQueryWrapper.eq(ArticleTag::getArticleId,article.getId());
        List<ArticleTag> articleTags = articleTagService.list(articleTagLambdaQueryWrapper);
        List<Long> tags = articleTags.stream().map(articleTag -> articleTag.getTagId()).collect(Collectors.toList());

        ArticleByIdVo articleVo = BeanCopyUtils.copyBean(article,ArticleByIdVo.class);
        articleVo.setTags(tags);
        return articleVo;
    }

    @Override
    //②然后才是修改文章
    public void edit(ArticleDto articleDto) {
        Article article = BeanCopyUtils.copyBean(articleDto, Article.class);
        //更新博客信息
        updateById(article);
        //删除原有的 标签和博客的关联
        LambdaQueryWrapper<ArticleTag> articleTagLambdaQueryWrapper = new LambdaQueryWrapper<>();
        articleTagLambdaQueryWrapper.eq(ArticleTag::getArticleId,article.getId());
        articleTagService.remove(articleTagLambdaQueryWrapper);
        //添加新的博客和标签的关联信息
        List<ArticleTag> articleTags = articleDto.getTags().stream()
                .map(tagId -> new ArticleTag(articleDto.getId(), tagId))
                .collect(Collectors.toList());
        articleTagService.saveBatch(articleTags);
    }

    /**
     * 审核文本内容
     *
     * @param text   文本内容
     * @return 是否审核通过
     */

    @Autowired
    private ContentCensor contentCensor;
    private boolean handleTextScan(String text) {
        try {
            Map<String, Object> map = contentCensor.textCensor(text);
            Short type = (Short) map.get("conclusionType");
            if (type.equals(TextCensorResultEnum.NON_COMPLIANCE.type())) {
                // 当前文本中存在违规内容
            }
            if (type.equals(TextCensorResultEnum.SUSPECTED.type())) {
                // 当前文本中存在不确定性内容
            }

            if (type.equals(TextCensorResultEnum.AUDIT_FAILED.type())) {
                // 自动审核失败，转人工审核
            }

            return type.equals(TextCensorResultEnum.COMPLIANCE.type());
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
}
